<template>
  <div class="GlobalSearch-wrap">
    <div class="input-wrap">
      <div class="input-box">
        <div class="left">
          <el-popover
            v-model="visible"
            :append-to-body="false"
            placement="bottom-start"
            popper-class="search-info-popover"
            trigger="click"
            width="298px"
          >
            <div class="info-box">
              <div class="head">
                <span>保存检索项</span>
                <el-link class="is-icon" @click="newSearch">新建检索项</el-link>
              </div>
              <ul v-if="conditionList.length" class="content">
                <el-tooltip
                  v-for="(item, index) in conditionList"
                  :key="index"
                  :content="item.searchCondition"
                  effect="dark"
                  placement="bottom"
                >
                  <li>
                    <span class="name" @click="nameClick(item)">{{
                      item.alias
                    }}</span>
                    <span class="li-btn">
                      <el-tooltip
                        content="编辑"
                        effect="dark"
                        placement="bottom"
                      >
                        <i class="vul-icon-edit" @click="editClick(item)"></i>
                      </el-tooltip>
                      <el-tooltip
                        content="删除"
                        effect="dark"
                        placement="bottom"
                      >
                        <i
                          class="vul-icon-delete"
                          @click="deleteClick(item)"
                        ></i>
                      </el-tooltip>
                    </span>
                  </li>
                </el-tooltip>
              </ul>
              <div v-if="!conditionList.length" class="no-data">
                <i class="vul-icon-sensitive"></i>
                <span>暂无保存的检索项</span>
              </div>
            </div>
            <template v-slot:reference>
              <span class="btn">
                <i class="vul-icon-task"></i>
                <el-icon><ArrowDown /></el-icon>
              </span>
            </template>
          </el-popover>
        </div>
        <div class="right">
          <el-input
            v-model="searchInput"
            clearable
            placeholder="请输入检索语句"
            @blur="blurFn"
            @clear="searchClick"
            @focus="focusFn"
            @input="setSelectVal"
            @keyup.enter.native="searchClick"
          >
          </el-input>
          <div v-if="selectVisible" class="select-wrap">
            <ul v-if="selectList.length">
              <li
                v-for="(item, index) in selectList"
                :key="index"
                @click="selectClick(item)"
              >
                {{ item.label }}
              </li>
            </ul>
            <div v-else class="no-data">
              <i class="vul-icon-sensitive"></i>
              <span>暂无数据</span>
            </div>
          </div>
        </div>
      </div>
      <div class="btn-box">
        <el-button type="primary" @click="searchClick">查询</el-button>
        <el-button type="info" @click="resetClick">重置</el-button>

        <el-tooltip
          class="item"
          content="添加过滤条件"
          effect="dark"
          placement="bottom"
        >
          <div class="high-search" @click="showSearch">
            <i class="vul-icon-syntax"></i>
          </div>
        </el-tooltip>
      </div>
    </div>
    <!-- 筛选条件 -->
    <AdvancedGraph
      ref="advancedGraph"
      :category="category"
      :search-text="searchInput"
      class="advanced-graph"
      @advancedSearch="advancedSearch"
    ></AdvancedGraph>
    <!-- 高级检索 -->
    <SearchPop
      v-if="showAdvancedSearchPop"
      :category="category"
      :is-show.sync="showAdvancedSearchPop"
      :search-text="searchInput"
      @advancedSearch="advancedSearch"
      @closeDia="closeDia"
    ></SearchPop>
    <el-dialog
      v-model="dialogVisible"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :modal-append-to-body="false"
      :title="dialogTitle"
      width="640px"
    >
      <div class="dialog-body">
        <el-form
          ref="ruleFormRef"
          :model="ruleForm"
          :rules="rules"
          class="ruleForm"
          label-width="100px"
        >
          <el-form-item label="名称：" prop="alias">
            <el-input
              v-model.trim="ruleForm.alias"
              maxlength="20"
              placeholder="请输入名称(长度限制20字符)"
              size="default"
            ></el-input>
          </el-form-item>
          <el-form-item label="检索条件：" prop="searchCondition">
            <el-input
              v-model.trim="ruleForm.searchCondition"
              placeholder="请输入检索条件"
              size="small"
              type="textarea"
            ></el-input>
          </el-form-item>
          <el-form-item label="描述：">
            <el-input
              v-model.trim="ruleForm.description"
              maxlength="100"
              show-word-limit
              type="textarea"
            ></el-input>
          </el-form-item>
        </el-form>
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button size="small" @click="cancel">取 消</el-button>
          <el-button
            size="small"
            type="primary"
            @click="submitForm(ruleFormRef)"
          >
            保 存
          </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import {
  computed,
  defineEmits,
  defineProps,
  onMounted,
  reactive,
  ref,
  Ref,
  watchEffect,
} from 'vue';
import { useStore } from 'vuex';
import type { FormInstance, FormRules } from 'element-plus';
import { ElMessage } from 'element-plus';

const store = useStore();
const emit = defineEmits(['searchClick']);

const props = defineProps({
  conditionVal: {
    type: String,
    default: '',
  },
  category: {
    type: String,
    default: '',
  },
});
const ruleFormRef = ref<FormInstance>();
let searchInput = ref('');

interface SelectItem {
  label: any;
  value: any;
}

let selectList: Ref<SelectItem[]> = ref([]);
let selectVisible = ref(false);
let visible = ref(false);
let dialogVisible = ref(false);
let dialogTitle = ref('新建检索项');

interface RuleFormType {
  id: any;
  scene: any; // 应用场景, 可不填;
  alias: any;
  searchCondition: any;
  description: any;
}

interface RuleForm {
  id: string;
  scene: any;
  alias: string;
  searchCondition: string;
  description: string;
}

let ruleForm = reactive<RuleForm>({
  id: '',
  scene: 'attack', // 应用场景, 可不填;
  alias: '',
  searchCondition: '',
  description: '',
});
let rules = reactive<FormRules<RuleForm>>({
  alias: [{ required: true, message: '请输入名称', trigger: 'blur' }],
  searchCondition: [
    { required: true, message: '请输入检索条件', trigger: 'blur' },
  ],
});
let showAdvancedSearchPop = ref(false);
let conditionList: Ref<RuleFormType[]> = ref([]);
watchEffect(() => {
  searchInput.value = props.conditionVal;
});

onMounted(() => {
  getCondition();
  document.addEventListener('click', bodyClick);
});
const cancel = () => {
  dialogVisible.value = false;
};
const bodyClick = (e) => {
  const select = document.querySelector('.select-wrap');
  if (select && !select.contains(e.target)) {
    // if (searchInput.value.focus()) {
    // }
    // selectVisible.value = false
  }
};
const focusFn = () => {
  // selectVisible.value = true
};
const blurFn = () => {
  if (!selectList.value.length) {
    selectVisible.value = false;
  }
};
const setSelectVal = () => {
  interface SelectItem {
    label: any;
    value: any;
  }

  let selectVal: SelectItem[] = [];
  const inputVal = searchInput.value.toLowerCase();
  const advancedSearchOpts = computed(
    () => store.state.attack.advancedSearchOpts,
  );
  if (inputVal.startsWith('w')) {
    selectVal.push({
      label: 'web',
      value: 'web',
    });
  }
  if (inputVal.startsWith('i')) {
    selectVal.push({
      label: 'ip',
      value: 'ip',
    });
  }
  if (inputVal.startsWith('d')) {
    selectVal.push({
      label: 'domain',
      value: 'domain',
    });
    selectVal.push({
      label: 'darknet',
      value: 'darknet',
    });
  }
  if (inputVal.startsWith('a')) {
    selectVal.push({
      label: 'app',
      value: 'app',
    });
  }
  if (inputVal.startsWith('b')) {
    selectVal.push({
      label: 'business',
      value: 'business',
    });
  }
  if (inputVal.startsWith('c')) {
    selectVal.push({
      label: 'code',
      value: 'code',
    });
  }

  if (inputVal.startsWith('web.')) {
    selectVal = advancedSearchOpts.value['web'];
  }
  if (inputVal.startsWith('ip.')) {
    selectVal = advancedSearchOpts['ip'];
  }
  if (inputVal.startsWith('domain.')) {
    selectVal = advancedSearchOpts['domain'];
  }
  if (inputVal.startsWith('darknet.')) {
    selectVal = advancedSearchOpts['darknet'];
  }
  if (inputVal.startsWith('app.')) {
    selectVal = advancedSearchOpts['app'];
  }
  if (inputVal.startsWith('business.')) {
    selectVal = advancedSearchOpts['business'];
  }
  if (inputVal.startsWith('code.')) {
    selectVal = advancedSearchOpts['code'];
  }

  selectList.value = selectVal;
};

const selectClick = (item) => {
  if (searchInput.value.includes('.')) {
    if (searchInput.value.endsWith('.')) {
      searchInput.value += item.value;
      selectVisible.value = false;
      return;
    } else {
      const start = searchInput.value.split('.')[0];
      searchInput.value = `${start}.${item.value}`;
      selectVisible.value = false;
      return;
    }
  }
  searchInput.value = item.value;
};
const openPopover = () => {
  visible.value = true;
};

const getInputVal = () => {
  return searchInput.value;
};

const searchClick = () => {
  emit('searchClick', searchInput.value);
};

const resetClick = () => {
  searchInput.value = '';
  searchClick();
};

const showSearch = () => {
  showAdvancedSearchPop.value = true;
};

const newSearch = () => {
  if (!searchInput.value) {
    ElMessage.error('请输入检索语句');
    return;
  }
  dialogTitle.value = '新建检索项';
  dialogVisible.value = true;
  ruleForm.searchCondition = searchInput.value;
};

const advancedSearch = (searchText, flag) => {
  searchInput.value = searchText;
  searchClick();
};

const closeDia = (val) => {
  showAdvancedSearchPop.value = val;
};

const sureClick = () => {
  dialogVisible.value = false;
};

const submitForm = async (formEl: FormInstance | undefined) => {
      if (!formEl) return;
      formEl.validate( async(valid, fields) => {
        if (valid) {
          let res
          if (dialogTitle.value === '新建检索项') {
            res = await store.dispatch(
              'attack/addCondition',
              ruleForm
            )
          } else {
            res = await store.dispatch(
              'attack/editCondition',
              ruleForm
            )
          }
          if (res.code !== 0) {
            return
          }
          dialogVisible.value = false
          getCondition()
          resetCondition()
        } else {
          return false
        }
      })
    }



const getCondition = async () => {
  const { code, data = {} } = await store.dispatch('attack/getCondition', {
    scene: 'attack', // 场景
    alias: '', // 别名, 右模糊查询
    pageSize: 10000,
    pageNumber: 1,
  });
  if (code !== 0) {
    return;
  }
  conditionList.value = data.list;
};

const nameClick = (item) => {
  searchInput.value = item.searchCondition;
  searchClick();
};

const resetCondition = () => {
  dialogTitle.value = '新建检索项';
  ruleForm.id = '';
  ruleForm.scene = 'attack';
  ruleForm.alias = '';
  ruleForm.searchCondition = '';
  ruleForm.description = '';
};

const editClick = (item: any) => {
  dialogVisible.value = true;
  dialogTitle.value = '编辑检索项';
  ruleForm = item;
};

const deleteClick = async (item) => {
  const { code } = await store.dispatch('attack/deleteCondition', {
    id: item.id,
  });
  if (code !== 0) {
    return;
  }
  await getCondition();
};
</script>
<style lang="scss" scoped>
.GlobalSearch-wrap {
  .input-wrap {
    display: flex;

    .input-box {
      flex: 1;
      display: flex;
      align-items: center;

      .left {
        width: 56px;
        height: 32px;
        display: flex;
        align-items: center;
        justify-content: center;
        border-radius: 4px 0px 0px 4px;
        box-sizing: border-box;
        border: 1px solid rgb(220, 223, 230);
        // border: 1px solid #3c3f5e;
        // background: rgba(41, 45, 76, 0.5);
        // color: rgba(255, 255, 255, 0.8);
        cursor: pointer;

        .btn {
          display: flex;
          align-items: center;
          justify-content: center;
        }
      }

      .right {
        flex: 1;
        position: relative;

        .select-wrap {
          width: 100%;
          position: absolute;
          top: 32px;
          left: 0px;
          z-index: 999;
          background: #191c34;
          box-sizing: border-box;
          border: 1px solid rgba(58, 125, 255, 0.3);
          box-shadow: 0px 10px 17px 0px rgba(0, 0, 0, 0.3);
          max-height: 285px;
          min-height: 100px;
          overflow-y: auto;

          > ul {
            li {
              display: flex;
              align-items: center;
              // justify-content: space-between;
              height: 30px;
              padding: 0px 15px;
              cursor: pointer;

              &:hover {
                background: rgba(255, 255, 255, 0.1);
              }
            }
          }

          .no-data {
            height: 100px;
            color: rgba(255, 255, 255, 0.8);
            font-size: 14px;
            display: flex;
            align-items: center;
            justify-content: center;

            i {
              margin-right: 8px;
              color: #ffc100;
            }
          }
        }
      }
    }

    .btn-box {
      display: flex;
      align-items: center;
      margin-left: 8px;

      .el-button {
        border: none;
        font-family: PingFangSC-Regular;
        font-size: 14px;
        margin: 0px;
      }

      .el-button + .el-button {
        margin-left: 8px;
      }

      .high-search {
        width: 32px;
        height: 32px;
        border-radius: 4px;
        box-sizing: border-box;
        border: 1px solid rgba(0, 0, 0, 0.2);
        display: flex;
        align-items: center;
        justify-content: center;
        margin-left: 8px;
        cursor: pointer;

        &:hover {
          border: 1px solid #0289f7;

          i {
            color: #0289f7;
          }
        }

        i {
          font-size: 20px;
          // color: rgba(255, 255, 255, 0.8);
        }
      }
    }
  }
}
</style>
<style lang="scss">
.search-info-popover {
  width: 298px;

  .info-box {
    .head {
      @include flexBox($justifyContent: space-between);
      height: 54px;
      line-height: 54px;
      letter-spacing: 0em;
      // color: rgba(255, 255, 255, 0.9);
      // border-bottom: 1px solid rgba(255, 255, 255, 0.1);
      padding: 0px 16px;

      // span {
      //   &:first-child {
      //     // color: rgba(255, 255, 255, 0.9);
      //   }

      //   &:last-child {
      //     // color: rgba(2, 137, 247, 0.9);
      //   }
      // }
    }

    .content {
      height: 210px;
      overflow-y: auto;

      > li {
        display: flex;
        align-items: center;
        justify-content: space-between;
        height: 30px;
        padding: 0px 15px;

        &:hover {
          background: #eee;

          .li-btn {
            display: block;
          }
        }

        .name {
          font-family: PingFangSC-Regular;
          font-size: 14px;
          // color: rgba(255, 255, 255, 0.9);
        }

        .li-btn {
          display: none;

          i {
            font-size: 16px;
          }

          .vul-icon-edit {
            color: #0289f7;
          }

          .vul-icon-delete {
            color: #ff4c4c;
            margin-left: 10px;
          }
        }
      }
    }

    .no-data {
      height: 210px;
      color: rgba(255, 255, 255, 0.8);
      font-size: 14px;
      display: flex;
      align-items: center;
      justify-content: center;

      i {
        margin-right: 8px;
        color: #ffc100;
      }
    }
  }
}
</style>
